// 封装自定义hook useStorage
import { useSyncExternalStore } from "react";
/**
 * useSyncExternalStore
 * 第一个参数 subscribe：用来订阅数据源的变化，接收一个回调函数，在数据源更新时调用该回调函数。
 * 第二个参数 getSnapshot：获取当前数据源的快照（当前状态）。
 * 第三个参数 getServerSnapshot?：在服务器端渲染时用来获取数据源的快照。
 */

/**
 * description: 自定义hook useStorage
 * @param key 键
 * @param defaultValue 默认值
 */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const useStorage = (key: string, defaultValue?: any) => {
  // 触发订阅
  const subscribe = (callback: () => void) => {
    window.addEventListener("storage", callback);
    return () => {
      window.removeEventListener("storage", callback);
    };
  };

  //从localStorage中获取数据 如果读不到返回默认值
  const getSnapshot = () => {
    // tip : 如果返回是引用类型需要判断新值和旧值比较 防止render死循环
    const storageValue = localStorage.getItem(key);
    return storageValue ? JSON.parse(storageValue) : defaultValue;
  };

  const state = useSyncExternalStore(subscribe, getSnapshot);

  //修改state
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const setState = (value: any) => {
    localStorage.setItem(key, JSON.stringify(value));
    window.dispatchEvent(new StorageEvent("storage")); //tip:手动触发storage事件
  };

  return [state, setState];
};
